package com.shou.weixin;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;

import com.google.gson.JsonObject;
import com.shou.entity.User;
import com.shou.util.FileUtil;
import com.shou.util.MySecureProtocolSocketFactory;

import net.sf.json.JSONObject;



/**
 * 微信公众平台 处理工具类   调用微信接口时均使用https协议 get请求
 */
public class WeixinHandler {
	private String WEIXIN_AppId;
	private String WEIXIN_AppSecret;
	private HttpClient client = new HttpClient();
	private WeixinMsg weixinMsg = new WeixinMsg();
	private String accessToken = null;
	public static final String mphelpOpenid = "oR5Gjjl_eiZoUpGozMo7dbBJ362A"; //微信助手openId
	
	/**
	 * 构造方法初始化微信appid appsecret
	 * 
	 * @param appId
	 * @param appSecret
	 */
	public WeixinHandler(String appId, String appSecret) {
		this.WEIXIN_AppId = appId;
		this.WEIXIN_AppSecret = appSecret;		
	}
	
	/**
	 * 构造方法 通过accessToken构建微信对象
	 * @param accessToken
	 */
	public WeixinHandler(String accessToken) {
		ProtocolSocketFactory fcty = new MySecureProtocolSocketFactory();
		Protocol.registerProtocol("https", new Protocol("https", fcty, 443));
		System.setProperty ("jsse.enableSNIExtension", "false");
		this.accessToken = accessToken;
	}
	
	/**
	 * 直接通过appId和appSecret获取accessToken
	 * 返回JSON格式  {"access_token":"ACCESS_TOKEN","expires_in":7200} 
	 * @param appId
	 * @param appSecret
	 * @return
	 */
	public static String getAccessToken(String appId, String appSecret){
		String accessToken = null;
		HttpClient client = new HttpClient();
		WeixinMsg weixinMsg = new WeixinMsg();
		
		try {
			ProtocolSocketFactory fcty = new MySecureProtocolSocketFactory();
			Protocol.registerProtocol("https", new Protocol("https", fcty, 443));
			GetMethod post = new GetMethod(
					"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+ appId + "&secret=" + appSecret);
			post.setRequestHeader("Connection", "Keep-Alive");
			post.setRequestHeader("Cache-Control", "no-cache");
			int status;
			status = client.executeMethod(post);
			if (status == HttpStatus.SC_OK) {
				String content = post.getResponseBodyAsString();	
				JSONObject json = JSONObject.fromObject(content);
				//JSONObject json = JSON.parseObject(content);
				if (json.get("access_token") != null) {
					accessToken = json.get("access_token").toString();
				} else {
					weixinMsg.setMsg(json.get("errcode").toString());
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return accessToken;
	}
	
	/**
	 * 生成带参数二维码步骤1：
	 * 账号管理  - 通过场景内容获得二维码内容 
	 * @param jsonString json字符串参数
	 * @return
	 */
	public String getTicket(String jsonString) {
		String url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token="
				+ accessToken;
		String ticket = null;

		try {
			PostMethod post = new PostMethod(url);
			post.setRequestEntity(new StringRequestEntity(jsonString, null, "utf-8"));
			post.getParams().setContentCharset("utf-8");
			String respStr = "";
			client.executeMethod(post);
			respStr = post.getResponseBodyAsString();
			JSONObject json = JSONObject.fromObject(respStr);
			if (json.get("ticket") != null) {
				ticket = (String) json.get("ticket");
				// System.out.println(ticket);
			} else {
				weixinMsg.setMsg(json.get("errcode").toString());
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (HttpException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return ticket;
	}
	
	
	/**
	 *
	 * 账号管理  - 生成带参数二维码步骤2：
	 * 通过ticket和文件路径生成二维码 
	 * 此二维码用于给用户关注公众号，并推送消息给开发者
	 * @param ticket
	 * @param path
	 * @return
	 */
	public String generateQrCode(String ticket, String path) {
		String url = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket="
				+ ticket;
		String picUrl = null;
		
		int BUFFER = 1024;
		GetMethod httpGet = new GetMethod(url);
		httpGet.getParams().setContentCharset("utf-8");
		try {
			client.executeMethod(httpGet);
			
			String newFileName = FileUtil.newFileName("test.jpg");
			String newPath = path + newFileName;
			File file = new File(newPath);
			if (!file.exists()) {
				file.createNewFile();
			}
			
			InputStream in = httpGet.getResponseBodyAsStream();
			FileOutputStream out = new FileOutputStream(new File(newPath));
			byte[] b = new byte[BUFFER];
			int len = 0;
			
			StringBuffer   fstr   =   new   StringBuffer(); 
			while ((len = in.read(b)) != -1) {
				out.write(b, 0, len);
				fstr.append(new   String(b, 0, len)); 
			}
			in.close();
			out.close();
			
			if(fstr.toString().contains("errcode")) {
				JSONObject json = JSONObject.fromObject(fstr.toString());
				//JSONObject json = JSONObject.parseObject(fstr.toString());
				weixinMsg.setMsg(json.get("errcode").toString());
			} else {
				picUrl = newFileName;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			httpGet.releaseConnection();
		}
		
		return picUrl;
	}
	
	/**
	 * 通过ticket和文件路径生成二维码(文件以ticket命名)
	 * @param ticket
	 * @param path
	 * @return
	 */
	public String generateQrCodewithTicketName(String ticket, String path,String code) {
		String url = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket="
				+ ticket;
		String picUrl = null;
		
		int BUFFER = 1024;
		GetMethod httpGet = new GetMethod(url);
		httpGet.getParams().setContentCharset("utf-8");
		try {
			client.executeMethod(httpGet);
			
			String newFileName = code+".jpg";
			String newPath = path + newFileName;
			File file = new File(newPath);
			if (!file.exists()) {
				file.createNewFile();
			}
			
			InputStream in = httpGet.getResponseBodyAsStream();
			FileOutputStream out = new FileOutputStream(new File(newPath));
			byte[] b = new byte[BUFFER];
			int len = 0;
			
			StringBuffer   fstr   =   new   StringBuffer(); 
			while ((len = in.read(b)) != -1) {
				out.write(b, 0, len);
				fstr.append(new   String(b, 0, len)); 
			}
			in.close();
			out.close();
			
			if(fstr.toString().contains("errcode")) {
				//JSONObject json = JSON.parseObject(fstr.toString());
				JSONObject json = JSONObject.fromObject(fstr.toString());
				weixinMsg.setMsg(json.get("errcode").toString());
			} else {
				picUrl = newFileName;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			httpGet.releaseConnection();
		}
		
		return picUrl;
	}

	/**
	 * 用户管理 - 获取关注此公众号的用户列表
	 * 通过openId获得用户openId列表   如果从头获取 参数就传 ""
	 * 返回数据格式 {"total":2,"count":2,"data":{"openid":["o4I09xISR4ej1Qd-5tt65OJ4PaF8","o4I09xJERH7stcM2lhusoVxK5mB4"]},"next_openid":"o4I09xJERH7stcM2lhusoVxK5mB4"}
	 * @param next_openid
	 * @return 
	 */
	public JSONObject getUserList(String next_openid) {
		
		String url = "https://api.weixin.qq.com/cgi-bin/user/get?access_token="
				+ accessToken;
		if(next_openid!=null){
			url+="&next_openid="+next_openid;
		}
		JSONObject returnJson = null;

		GetMethod post = new GetMethod(url);
		post.getParams().setContentCharset("utf-8");
		String respStr = "";
		try {
			client.executeMethod(post);
			respStr = post.getResponseBodyAsString();
			returnJson = JSONObject.fromObject(respStr);
			if (respStr.contains("errcode")) {
				weixinMsg.setMsg(returnJson.get("errcode").toString());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return returnJson;
	}

	/**
	 * 通过openid获取用户信息
	 * 用户管理 - 获取用户基本信息（UnionID机制）
	 * @param openId
	 * @return
	 */
	public User getUserInfo(String openId) {
		String url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + accessToken + "&openid=" + openId;
		User weixinUser = null;

		GetMethod post = new GetMethod(url);
		post.getParams().setContentCharset("utf-8");
		String respStr = "";
		try {
			client.executeMethod(post);
			
			respStr = post.getResponseBodyAsString();
			
			try {				
				JSONObject jsonObject =	JSONObject.fromObject(respStr);
				weixinUser = (User)JSONObject.toBean(jsonObject,User.class);				
			} catch (Exception e) {
				JSONObject returnJson =	JSONObject.fromObject(respStr);
				weixinMsg.setMsg(returnJson.get("errcode").toString());
			}
			
		} catch (HttpException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return weixinUser;
	}

	
	public static void main(String[] args) {				
		System.out.println(WeixinHandler.getAccessToken("wx69d041c3f5edb145","0e8f423a4c24d99a67e74615dba36fa8"));
	}

	public WeixinMsg getWeixinMsg() {
		return weixinMsg;
	}

	public void setWeixinMsg(WeixinMsg weixinMsg) {
		this.weixinMsg = weixinMsg;
	}

	public String getAccessToken() {
		return accessToken;
	}

	public void setAccessToken(String accessToken) {
		this.accessToken = accessToken;
	}
}